<?php

namespace Divine\Http\Message;

class RequestMessage extends AbstractMessage
{
    /**
     * The method to perform on the requested resource.
     *
     * @var string
     */
    protected $_method;
    /**
     * The uniform resource identifier of the request.
     *
     * @var string
     */
    protected $_uri;

    const METHOD_GET     = 'GET';
    const METHOD_POST    = 'POST';
    const METHOD_PUT     = 'PUT';
    const METHOD_DELETE  = 'DELETE';
    const METHOD_TRACE   = 'TRACE';
    const METHOD_CONNECT = 'CONNECT';
    const METHOD_OPTIONS = 'OPTIONS';

    /**
     * Creates a new Divine\Http\Message\RequestMessage instance.
     *
     * @param string $method The HTTP request method.
     * @param string $uri The unique resource identifier of the request.
     * @param string $httpVersion The HTTP Version of the message.
     * @param array $headers HTTP headers as an array where the index is the field name.
     * @param string $body An optional message body.
     */
    public function __construct($method, $uri, $httpVersion = parent::PROTOCOL_HTTP_1_1, array $headers = array(),
                                $body = NULL)
    {
        $this->_setMethod($method);
        $this->_setUri($uri);
        $this->_setHttpVersion($httpVersion);
        $this->_setHeaders($headers);
        $this->_setBody($body);
    }

    /**
     * Set the method for the request.
     *
     * @param string $method An HTTP request method.
     * @throws \Divine\Http\Exception\ServerException Thrown if the request method is not implemented by the server.
     */
    protected function _setMethod($method)
    {
        if (!static::_isValidMethod($method))
        {
            throw new \UnexpectedValueException('Unknown HTTP request method: ' . $method);
        }

        $this->_method = $method;
    }

    /**
     * Set the uri for the request.
     *
     * @param string $uri
     */
    protected function _setUri($uri)
    {
        $this->_uri = $uri;
    }

    /**
     * Returns the method of the request.
     *
     * @return string
     */
    public function getMethod()
    {
        return $this->_method;
    }

    /**
     * Returns the URI of the request.
     *
     * @return string
     */
    public function getUri()
    {
        return $this->_uri;
    }

    /**
     * Checks for a valid HTTP request method.
     *
     * @param int $statusCode A numeric HTTP response status code.
     * @return boolean
     */
    protected static function _isValidMethod($method)
    {
        $validMethods = array
        (
            static::METHOD_GET,
            static::METHOD_POST,
            static::METHOD_PUT,
            static::METHOD_DELETE,
            static::METHOD_TRACE,
            static::METHOD_CONNECT,
            static::METHOD_OPTIONS,
        );

        return in_array($method, $validMethods);
    }
}